%{
#include <stdio.h>
  
%}

%token IDENTIFIER, MAIN, DOC, LABEL, PIC, OBJ, FOR, SETSIZE, SETFONT, SETFONTSIZE, PATH, DIST, POSITION,
  	DIRECTION, ANGLE, DISTANCE, TO, INNER, LEFT, MIDDLE, RIGHT, RIGHT, TOP, DOWN, FROM, CONTENT,
       RETURN, DEFAULT, FONT, SIZE, TYPE, CONTAINER, POLY, LETOUT, Z-AXIS, AT, AND, OR,  WITH, CONSTANT,
	UNDERLINE, EQUAL, ASSIGN, NOTEQ, DOT, GE, GT, LBRAC, LE, LT, LPAREN, MINUS,  PLUS, RBRAC, RPAREN,
 	SEMICOLON, SLASH, STAR, MOD, LCURL, RCURL, COMMA	

%left OR
%left AND

%%
code:
     declaration
  |  code declaration
  ;

declaration:
     function_definition
  |  variable_declaration
  ; 
variable_declaration:
     type_specifier init_declarator_list SEMICOLON
    ;

variable_declaration_list:
     variable_declaration
  |  variable_declaration_list COMMA variable_declaration
  ;


function_definition:
     MAIN LPAREN RLPAREN compound_statement { printf("\npublic static void main(String[] arg){\n");
					      printf("%s\n", C_State);
					      printf("}\n");
					    }
  |  type_specifiers IDENTIFIER LPAREN variable_declaration_list RPAREN  compound_statement{
						    
							printf("\n private static %s %s( %s ) {\n", Type_S, $2, V_D_L);
							printf("%s\n", C_State);
							printf("}\n");
						}
  |  type_specifiers IDENTIFIER LPAREN compound_statement RPAREN{ 
							printf("\n private static %s %s( ) {\n", Type_S, $2);
							printf("%s\n", C_State);
							printf("}\n");}
  |  IDENTIFIER LPAREN variable_declaration_list RPAREN compound_statement{

							printf("\n private static void %s( %s ) {\n", Type_S, $2, V_D_L);
							printf("%s\n", C_State);
							printf("}\n");}
  |  IDENTIFIER LPAREN compound_statement RPAREN{
  
							printf("\n private static void %s( ) {\n", Type_S, $2);
							printf("%s\n", C_State);
							printf("}\n");}
;

type_specifier:
     NUMBER {sprintf(Type_S, "int");}
  |  STRING {sprintf(Type_S, "string");}
  |  DOC    {sprintf(Type_S, "MDoc");}
  |  OBJ    {sprintf(Type_S, "obj");}
  |  LABEL  {sprintf(Type_S, "Mlabel");}
  |  PIC    {sprintf(Type_S, "Mpic");}
  |  CONTAINER {sprintf(Type_S, "Mcontainer");}
  ;
init_declarator_list:
     init_declarator
  |  init_declarator_list COMMA init_declarator
  ;
init_declarator:
     IDENTIFIER
     array_declartor
  ;
array_declartor:
    IDENTIFIER LBRAC unary_expr LBRAC  
    ;

expression:
     assignment_expr
  |  expression COMMA assignment_expr
    ;

assignment_expr:
	logical_OR_expr
    |	unary_expr assignment_operator assignment_expr
    ;
assignment_operator:
     ASSIGN
  ;

logical_OR_expr:
     logical_AND_expr
  |  logical_OR_expr OR logical_AND_expr
  ;

logical_AND_expr:
     equality_expr
  |  logical_AND_expr AND equality_expr
  ;

equality_expr:
     relational_expr
  |  equality_expr EQUAL relational_expr
  |  equality_expr NOTEQ relational_expr
  ;

relational_expr:
     additive_expr
  |  relational_expr LT  additive_expr
  |  relational_expr GT  additive_expr
  |  relational_expr GE  additive_expr
  |  relational_expr LE  additive_expr
  ;


additive_expr:
     multiplicative_expr
  |  additive_expr PLUS multiplicative_expr
  |  additive_expr MINUS multiplicative_expr
  ;

multiplicative_expr:
     cast_expr
  |  multiplicative_expr STAR cast_expr
  |  multiplicative_expr SLASH cast_expr
  |  multiplicative_expr MOD cast_expr
  ;

cast_expr:
     unary_expr
  |  LPAREN type_name RPAREN cast_expr
  ;

unary_expr:
     IDENTIFIER
  |  IDENTIFIER DOT  IDENTIFIER
  |  CONSTANT
  |  IDENTIFIER LBRAC unary_expr RBRAC
;

statement:
     compound_statement
  |  expression_statement
  |  selection_statement
  |  iteration_statement
  ;
expression_statement:
     expression SEMICOLON
  |   SEMICOLON
  ;
selection_statement:
     IF LPAREN expression RPAREN statement
  |  IF LPAREN expression RPAREN statement ELSE statement
  ;
iteration_statement:
  |  FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement
  |  FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement
  |  FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement
  |  FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement
  |  FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement
  |  FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement
  |  FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement
  |  FOR LPAREN SEMICOLON SEMICOLON RPAREN statement
  |  FOR LPAREN declaration SEMICOLON expression SEMICOLON expression RPAREN statement
  |  FOR LPAREN declaration SEMICOLON expression SEMICOLON RPAREN statement
  |  FOR LPAREN declaration SEMICOLON SEMICOLON expression RPAREN statement
  |  FOR LPAREN declaration SEMICOLON SEMICOLON RPAREN statement
  ;


compound_statement:
     LCURL block_item_list RCURL
  |  LCURL RCURL
  ;

block_item_list:
     block_item
  |  block_item_list block_item
  ;

block_item:
     variable_declaration
  |  statement
  ;



line : line '\n'
     | '\n'
     |/*empty*/
     |error '\n' {yyerror("reenter previous line:");
     			yyerrok;}
     ;			
%%
int main(int argc, char *argv[])
{
	yyin = fopen(argv[1],"r");
	printf("package tests;\nimport mat.*;\n");
	printf("public class test{\n");
	yyparse();
	printf("}\n}\n");

	return 0;
}

int yerror(char *msg)
{
	printf("Errrrr~~\n", msg);
}
